/***************************************************************************************************
 * Copyright (c) 2015-2020 Intelligent Network System Ltd. All Rights Reserved. 
 * 
 * This software is the confidential and proprietary information of Founder. You shall not disclose
 * such Confidential Information and shall use it only in accordance with the terms of the 
 * agreements you entered into with Founder. 
***************************************************************************************************/

/***************************************************************************************************
 * INCLUDES
 */
#include "sx127x_spi.h"

#include <stdint.h>
#include <stdbool.h> 
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include "spi.h"
#include "sx127x_dio.h"



/***************************************************************************************************
 * MACROS
 */




/***************************************************************************************************
 * TYPEDEFS
 */
 
 
/***************************************************************************************************
 * CONSTANTS
 */


/***************************************************************************************************
 * GLOBAL VARIABLES
 */


/***************************************************************************************************
 * STATIC VARIABLES
 */



void *ispi_target = NULL;
char ispi_path[] = "/dev/spidev2.0";
int ispeed_hz = 6000000;
/***************************************************************************************************
 *  GLOBAL FUNCTIONS IMPLEMENTATION
 */
 
/*!
 * sx127x_SpiInit()
 */
void sx127x_SpiInit(void)
{
    int spi_stat = SPI_SUCCESS;

    if (ispi_target != NULL) {        
        printf("WARNING: concentrator was already connected\n");        
        spi_close(ispi_target);    
    }
    
    spi_stat = spi_open(&ispi_target, ispi_path, ispeed_hz);
    if (spi_stat != SPI_SUCCESS) {      
        printf("ERROR CONNECTING CONCENTRATOR\n");        
        return ;    
    }

}

/*!
 * sx127x_SpiDeInit()
 */
void sx127x_SpiDeInit(void)
{
    if (ispi_target != NULL) {        
        spi_close(ispi_target);        
        ispi_target = NULL;        
        printf("Note: success disconnecting the concentrator\n");            
    } else {        
        printf("WARNING: concentrator was already disconnected\n");        
    }
}

void sx127x_spi_write(uint8_t addr, uint8_t *buffer, uint8_t size)
{

	uint8_t tx_data[size + 1];

    tx_data[0] = addr;

    memcpy(tx_data + 1, buffer, size);
    
    struct spi_ioc_transfer spi_xfer[1];
    
    memset(spi_xfer, 0, sizeof(struct spi_ioc_transfer));
    
    spi_xfer[0].tx_buf = (unsigned long)tx_data;
    
    spi_xfer[0].len = size + 1;
    //spi_xfer[0].cs_change = 0;
    if (linux_spi_transfer(ispi_target, spi_xfer, 1) < 0) {
        printf("SX127X_ERROR: Error during spi write\n");
    }

}



void sx127x_spi_read(uint8_t addr, uint8_t *buffer, uint8_t size)
{
    struct spi_ioc_transfer spi_xfer[2];

    memset(spi_xfer, 0, 2 * sizeof(struct spi_ioc_transfer));

    spi_xfer[0].tx_buf = (unsigned long)&addr;

    spi_xfer[0].len = 1;
    //spi_xfer[0].cs_change = 0;

    spi_xfer[1].rx_buf = (unsigned long)buffer;

    spi_xfer[1].len = size;
    //spi_xfer[1].cs_change = 0;
    if (linux_spi_transfer(ispi_target, spi_xfer, 2) < 0) {

       printf("SX127X_ERROR :Error during spi read\n");

    }

}

void SX127xWrite( uint8_t addr, uint8_t data )
{
#if 0
    int spi_stat;
    
    spi_stat = lgw_spi_w(ispi_target, LGW_SPI_MUX_MODE0, 0, addr, data);
    if (spi_stat != LGW_SPI_SUCCESS) {      
        printf("ERROR in SX127xWrite\n");        
        return ;    
    }
#else
    SX127xWriteBuffer(addr, &data, 1);
#endif 
}

void SX127xRead( uint8_t addr, uint8_t *data )
{
#if 0
    int spi_stat;
    
    spi_stat = lgw_spi_r(ispi_target, LGW_SPI_MUX_MODE0, 0, addr, data);
    if (spi_stat != LGW_SPI_SUCCESS) {      
        printf("ERROR in sx1278_SpiReadByte\n");        
        return ;    
    }
#else
    SX127xReadBuffer(addr, data, 1);
    
#endif 
}

void SX127xWriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
#if 1
    int spi_stat;
    
    spi_stat = spi_wb(ispi_target, SPI_MUX_MODE0, 0, addr, buffer, size);
    if (spi_stat != SPI_SUCCESS) {      
        printf("ERROR in sx1278_SpiWrite\n");        
        return ;    
    }
#else
    //sx127x_DioNssSelect(true);
    sx127x_spi_write(addr | 0x80, buffer, size);
    //sx127x_DioNssSelect(false);
#endif 
}

void SX127xReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
#if 1
    int spi_stat;
    
    spi_stat = spi_rb(ispi_target, SPI_MUX_MODE0, 0, addr, buffer, size);
    if (spi_stat != SPI_SUCCESS) {      
        printf("ERROR in sx1278_SpiRead\n");        
        return;    
    }
#else
    //sx127x_DioNssSelect(true);
    sx127x_spi_read(addr & 0x7F, buffer, size);
    //sx127x_DioNssSelect(false);
#endif
}

void SX127xWriteFifo( uint8_t *buffer, uint8_t size )
{
    SX127xWriteBuffer( 0, buffer, size );
}

void SX127xReadFifo( uint8_t *buffer, uint8_t size )
{
    SX127xReadBuffer( 0, buffer, size );
}

/***************************************************************************************************
 * LOCAL FUNCTIONS IMPLEMENTATION
 */

/*!
 * sx127x_SpiDelay__()
 */
void sx127x_SpiDelay__( uint32_t a_u16DelayCnt )
{
    usleep(1000*a_u16DelayCnt);
}

/***************************************************************************************************
* HISTORY LIST
* 1. Create File by author @ data
*   context: here write modified history
*
***************************************************************************************************/
